package com.servlet;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.easywan.exception.RuleErrorException;


public abstract class AbsBaseUploadServlet extends HttpServlet{
	private static final long serialVersionUID = 1L;
	//private Map<String,Object> params = null;
	/**
	 * 初始化数据
	 * 1.初始化编码，固定为UTF-8
	 * 2.新建保存路径
	 * 3.新建压缩路径
	 * 4.初始化上传文件限制参数
	 * @param request
	 * @param response
	 * @throws RuleErrorException 
	 * @throws FileUploadException 
	 * @throws UnsupportedEncodingException 
	 */
	public void init(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, FileUploadException, RuleErrorException{
		response.setCharacterEncoding("UTF-8");
    	response.setContentType("text/html;charset=utf-8");
    
	    File saveFileDir = new File(getSavePath());
	    if (!saveFileDir.exists()) {
	        saveFileDir.mkdirs();
	    }
	    if(isDest()){
	        File destFileDir = new File(getDestPath());
	        if(!destFileDir.exists()){
	       	  saveFileDir.mkdirs();
	        }
	    }
        File tmpFile = new File(getTmpPath());
        if (!tmpFile.exists()) {
            // 创建临时目录
            tmpFile.mkdirs();
        }
        getParams(request);
        
	}
	public ServletFileUpload getUpload(){
		DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(1024 * 10);// 设置缓冲区的大小为100KB，如果不指定，那么默认缓冲区的大小是10KB
        factory.setRepository(new File(getTmpPath()));
         ServletFileUpload upload = new ServletFileUpload(factory);
     // 设置上传单个文件的最大值
        upload.setFileSizeMax(getFileSizeMax());// 10M
        // 设置上传文件总量的最大值，就是本次上传的所有文件的总和的最大值
        upload.setSizeMax(getSizeMax());// 100M
        return upload;
	}
	/**
	 * 默认是100M
	 * 批量上传的文件总共大小
	 * @return
	 */
	public Long getSizeMax(){
		return 1024 * 1024 * 100L;
	}
	/**
	 * 单个文件的大小
	 * @return
	 */
	public abstract	Long getFileSizeMax();
	/**
	 * 文件保存路径
	 * @return
	 */
	public abstract String getSavePath();
	/**
	 * 文件压缩保存路径
	 * @return
	 */
	public abstract String getDestPath();
	/**
	 * 临时文件保存路径
	 * 会自动创建保存路径
	 * @return
	 */
	public abstract String getTmpPath();
	/**
	 * 返回值为日期为目录+UUD
	 * @return
	 */
	public String getFileName(String f){
		Date date = new Date();
		@SuppressWarnings("deprecation")
		String datePath = date.getYear() + "/"+ (date.getMonth()+1)+"/"+date.getDate();
		File datePathFile = new File(getPath()+ "/" + datePath);
		if(!datePathFile.exists()){
			datePathFile.mkdirs();
		}
		String fileName = UUID.randomUUID().toString();
		return datePath + "/"+fileName +"_"+ f;
	}
	/**
	 * 判断是否是需要的后缀
	 * @return
	 */
	public abstract boolean isExt(String string);
	/**
	 * 将床底上来的参数封装为map
	 * @param request
	 * @return
	 * @throws FileUploadException
	 * @throws RuleErrorException
	 * @throws UnsupportedEncodingException
	 */
	public void getParams(HttpServletRequest request) throws FileUploadException, RuleErrorException, UnsupportedEncodingException{
		//if(params != null) return params;
		Map<String,Object> resultMap = new HashMap<String,Object>();
		ServletFileUpload upload = getUpload();
		List<FileItem> items = upload.parseRequest(request);
		Iterator<FileItem> itr = items.iterator();
		while (itr.hasNext()) {
        	 FileItem item = (FileItem) itr.next();
        	 if (item.isFormField()) {//获取普通参数
        		// 如果fileitem中封装的是普通的输入想数据
                 String name = item.getFieldName();
                 // 解决普通输入项数据中文乱码问题
                 String value = item.getString("UTF-8");
                 value = new String(value.getBytes("iso8859-1"),"UTF-8");
                 resultMap.put(name, value);
                 System.out.println(name + ":" +value);
        	 }else{
        		 String fileName = item.getName();
        		// 得到上传文件的文件名
                 if (fileName == null && fileName.trim().length() == 0) {
                     continue;
                 }
                 // 注意：不同的浏览器提交的文件名是不一样的，有些浏览器提交上来的文件名是带有路径的
                 // 如: C:\Users\H__D\Desktop\1.txt 而有些则是 ： 1.txt
                 // 处理获取到的上传文件的文件名的路径部分，只保留文件名部分
                 fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                 // 得到上传文件的扩展名
                 String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                 if(isExt(fileExt)){
                	
                 }else{
                	 throw new RuleErrorException();
                 }
                 resultMap.put(item.getFieldName(), item);
                 resultMap.put(item.getFieldName()+"fileName", fileName);
        	 }
        }
		//params = resultMap;
		request.setAttribute("params", resultMap);
	}
	
	/**
	 * 是否压缩
	 * @return
	 */
	public abstract boolean isDest();
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//super.doPost(req, resp);
		try {
			init(req, resp);
		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuleErrorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String getPath(){
		return getSavePath();
	}
	
}
